/**
  ******************************************************************************
  * @file    RFID_RC522_Config.h
  * @brief   RC522 RFID模块配置头文件
  * @version V2.1
  * @date    2023-05-20
  * @note    功能特性：
  *          - 支持STM32硬件SPI和GPIO控制
  *          - 完整寄存器地址定义
  *          - 多协议命令字宏定义
  *          - 硬件抽象层接口
  ******************************************************************************
  */

#ifndef __RFID_RC522_CONFIG_H
#define __RFID_RC522_CONFIG_H

#ifdef __cplusplus
 extern "C" {
#endif

/* 硬件依赖头文件 ----------------------------------------------------------*/
#include "stm32f10x.h"          // STM32标准外设库
#include "Delay.h"              // 精确延时函数
#include "USART1_Config.h"      // 调试串口配置
#include <string.h>

/* 硬件时序配置 ------------------------------------------------------------*/
#define RC522_Delay()    Delay_us(5)  // 标准操作延时

/* 通信协议命令字 ---------------------------------------------------------*/
// MF522操作命令

#define PCD_IDLE              0x00               //取消当前命令
#define PCD_AUTHENT           0x0E               //验证密钥
#define PCD_RECEIVE           0x08               //接收数据
#define PCD_TRANSMIT          0x04               //发送数据
#define PCD_TRANSCEIVE        0x0C               //发送并接收数据
#define PCD_RESETPHASE        0x0F               //复位
#define PCD_CALCCRC           0x03               //CRC计算

//Mifare_One卡片命令字

#define PICC_REQIDL           0x26               //寻天线区内未进入休眠状态
#define PICC_REQALL           0x52               //寻天线区内全部卡
#define PICC_ANTICOLL1        0x93               //防冲撞
#define PICC_ANTICOLL2        0x95               //防冲撞
#define PICC_AUTHENT1A        0x60               //验证A密钥
#define PICC_AUTHENT1B        0x61               //验证B密钥
#define PICC_READ             0x30               //读块
#define PICC_WRITE            0xA0               //写块
#define PICC_DECREMENT        0xC0               //扣款
#define PICC_INCREMENT        0xC1               //充值
#define PICC_RESTORE          0xC2               //调块数据到缓冲区
#define PICC_TRANSFER         0xB0               //保存缓冲区中数据
#define PICC_HALT             0x50               //休眠

/* 硬件参数定义 -----------------------------------------------------------*/
#define DEF_FIFO_LENGTH 64      // FIFO缓冲区大小
#define MAXRLEN         18      // 最大接收长度
#define UID_LENGTH      4       // 标准UID长度

/* 寄存器地址映射 ---------------------------------------------------------*/
// Page 0: 命令与状态
#define     RFU00                 0x00    
#define     CommandReg            0x01    
#define     ComIEnReg             0x02    
#define     DivlEnReg             0x03    
#define     ComIrqReg             0x04    
#define     DivIrqReg             0x05
#define     ErrorReg              0x06    
#define     Status1Reg            0x07    
#define     Status2Reg            0x08    
#define     FIFODataReg           0x09
#define     FIFOLevelReg          0x0A
#define     WaterLevelReg         0x0B
#define     ControlReg            0x0C
#define     BitFramingReg         0x0D
#define     CollReg               0x0E
#define     RFU0F                 0x0F
// Page 1: 通信模式    
#define     RFU10                 0x10
#define     ModeReg               0x11
#define     TxModeReg             0x12
#define     RxModeReg             0x13
#define     TxControlReg          0x14
#define     TxAutoReg             0x15
#define     TxSelReg              0x16
#define     RxSelReg              0x17
#define     RxThresholdReg        0x18
#define     DemodReg              0x19
#define     RFU1A                 0x1A
#define     RFU1B                 0x1B
#define     MifareReg             0x1C
#define     RFU1D                 0x1D
#define     RFU1E                 0x1E
#define     SerialSpeedReg        0x1F
// Page 2: 定时器与RF配置    
#define     RFU20                 0x20  
#define     CRCResultRegM         0x21
#define     CRCResultRegL         0x22
#define     RFU23                 0x23
#define     ModWidthReg           0x24
#define     RFU25                 0x25
#define     RFCfgReg              0x26
#define     GsNReg                0x27
#define     CWGsCfgReg            0x28
#define     ModGsCfgReg           0x29
#define     TModeReg              0x2A
#define     TPrescalerReg         0x2B
#define     TReloadRegH           0x2C
#define     TReloadRegL           0x2D
#define     TCounterValueRegH     0x2E
#define     TCounterValueRegL     0x2F
// PAGE 3      
#define     RFU30                 0x30
#define     TestSel1Reg           0x31
#define     TestSel2Reg           0x32
#define     TestPinEnReg          0x33
#define     TestPinValueReg       0x34
#define     TestBusReg            0x35
#define     AutoTestReg           0x36
#define     VersionReg            0x37
#define     AnalogTestReg         0x38
#define     TestDAC1Reg           0x39  
#define     TestDAC2Reg           0x3A   
#define     TestADCReg            0x3B   
#define     RFU3C                 0x3C   
#define     RFU3D                 0x3D   
#define     RFU3E                 0x3E   
#define     RFU3F		  		        0x3F


/* 状态码定义 -------------------------------------------------------------*/
#define MI_OK           (0)       // 操作成功
#define MI_NOTAGERR     (1)       // 无卡片响应
#define MI_ERR          (2)       // 通信错误

#define	SHAQU1	0X01
#define	KUAI4	0X04
#define	KUAI7	0X07
#define	REGCARD	0xa1
#define	CONSUME	0xa2
#define READCARD	0xa3
#define ADDMONEY	0xa4

//
//#define  spi_cs 1;
//sbit  spi_ck=P0^6;
//sbit  spi_mosi=P0^7;
//sbit  spi_miso=P4^1;
//sbit  spi_rst=P2^7;
#define SPIReadByte()	SPIWriteByte(0)
u8 SPIWriteByte(u8 byte);
void SPI1_Init(void);

#define SET_SPI_CS  (GPIOF->BSRR=0X01)
#define CLR_SPI_CS  (GPIOF->BRR=0X01)



#define SET_RC522RST  GPIOF->BSRR=0X02
#define CLR_RC522RST  GPIOF->BRR=0X02


/***********************RC522 函数宏定义**********************/
#define          RC522_CS_Enable()         GPIO_ResetBits ( GPIOA, GPIO_Pin_4 )
#define          RC522_CS_Disable()        GPIO_SetBits ( GPIOA, GPIO_Pin_4 )

#define          RC522_Reset_Enable()      GPIO_ResetBits( GPIOB, GPIO_Pin_0 )
#define          RC522_Reset_Disable()     GPIO_SetBits ( GPIOB, GPIO_Pin_0 )

#define          RC522_SCK_0()             GPIO_ResetBits( GPIOA, GPIO_Pin_5 )
#define          RC522_SCK_1()             GPIO_SetBits ( GPIOA, GPIO_Pin_5 )

#define          RC522_MOSI_0()            GPIO_ResetBits( GPIOA, GPIO_Pin_7 )
#define          RC522_MOSI_1()            GPIO_SetBits ( GPIOA, GPIO_Pin_7 )

#define          RC522_MISO_GET()          GPIO_ReadInputDataBit ( GPIOA, GPIO_Pin_6 )

/* 硬件控制层接口 ----------------------------------------------------------*/

/**
  * @brief  RC522主控制函数（需在循环中调用）
  */
void RC522_Handel(void);

/**
  * @brief  初始化RC522硬件接口
  * @note   包含SPI初始化和GPIO配置
  */
void RC522_Init(void);

/**
  * @brief  初始化SPI1控制器
  * @note   时钟配置为PCLK2/8，模式0
  */
void SPI1_Init(void);

/* 底层通信接口 ----------------------------------------------------------*/

/**
  * @brief  通过SPI发送单字节数据
  * @param  byte: 要发送的数据
  */
void SPI_RC522_SendByte(u8 byte);

/**
  * @brief  通过SPI读取单字节数据
  * @retval 接收到的数据
  */
u8 SPI_RC522_ReadByte(void);

/* 寄存器操作接口 --------------------------------------------------------*/

/**
  * @brief  读取RC522寄存器
  * @param  ucAddress: 寄存器地址
  * @retval 寄存器值
  */
u8 ReadRawRC(u8 ucAddress);

/**
  * @brief  写入RC522寄存器
  * @param  ucAddress: 寄存器地址
  * @param  ucValue: 要写入的值
  */
void WriteRawRC(u8 ucAddress, u8 ucValue);

/**
  * @brief  设置寄存器位掩码
  * @param  ucReg: 寄存器地址
  * @param  ucMask: 位掩码（如0x08）
  */
void SetBitMask(u8 ucReg, u8 ucMask);

/**
  * @brief  清除寄存器位掩码
  * @param  ucReg: 寄存器地址
  * @param  ucMask: 位掩码（如0x08）
  */
void ClearBitMask(u8 ucReg, u8 ucMask);

/* 射频场控制 ------------------------------------------------------------*/

/**
  * @brief  开启天线射频场
  * @note   会激活13.56MHz载波
  */
void PcdAntennaOn(void);

/**
  * @brief  关闭天线射频场
  */
void PcdAntennaOff(void);

/**
  * @brief  硬件复位RC522
  * @note   复位时间约10μs
  */
void PcdReset(void);

/**
  * @brief  配置ISO协议类型
  * @param  ucType: 协议类型 
  *         - 'A': ISO14443A (默认)
  *         - 'B': ISO14443B
  */
void M500PcdConfigISOType(u8 ucType);

/* 核心功能接口 ----------------------------------------------------------*/

/**
  * @brief  RC522通信主函数
  * @param  ucCommand: 命令字（PCD_XXX）
  * @param  pInData: 输入数据缓冲区
  * @param  ucInLenByte: 输入数据长度
  * @param  pOutData: 输出数据缓冲区
  * @param  pOutLenBit: 输出数据位数指针
  * @retval 操作状态（MI_OK/MI_ERR）
  */
char PcdComMF522(u8 ucCommand, u8 *pInData, u8 ucInLenByte,
                u8 *pOutData, u32 *pOutLenBit);

/**
  * @brief  寻卡请求
  * @param  ucReq_code: 请求模式
  *         - PICC_REQIDL: 寻未休眠卡
  *         - PICC_REQALL: 寻所有卡
  * @param  pTagType: 返回的卡片类型
  * @retval 操作状态
  */
char PcdRequest(u8 ucReq_code, u8 *pTagType);

/**
  * @brief  防冲突处理并获取UID
  * @param  pSnr: 返回的卡片UID（4字节）
  * @retval 操作状态
  */
char PcdAnticoll(u8 *pSnr);

/**
  * @brief  CRC计算函数
  * @param  pIndata: 输入数据
  * @param  ucLen: 数据长度
  * @param  pOutData: CRC结果（2字节）
  */
void CalulateCRC(u8 *pIndata, u8 ucLen, u8 *pOutData);

/**
  * @brief  选择卡片
  * @param  pSnr: 卡片UID（4字节）
  * @retval 操作状态
  */
char PcdSelect(u8 *pSnr);

/* 高级功能接口 ----------------------------------------------------------*/

/**
  * @brief  认证卡片密钥
  * @param  ucAuth_mode: 认证模式
  *         - PICC_AUTHENT1A: 密钥A
  *         - PICC_AUTHENT1B: 密钥B
  * @param  ucAddr: 块地址（0-63）
  * @param  pKey: 6字节密钥
  * @param  pSnr: 卡片UID（4字节）+BCC（2字节）
  * @retval 认证状态
  */
char PcdAuthState(u8 ucAuth_mode, u8 ucAddr, u8 *pKey, u8 *pSnr);

/**
  * @brief  写数据块
  * @param  ucAddr: 块地址（0-63）
  * @param  pData: 16字节数据
  * @retval 写入状态
  * @warning 禁止直接写扇区尾块
  */
char PcdWrite(u8 ucAddr, u8 *pData);

/**
  * @brief  读数据块
  * @param  ucAddr: 块地址（0-63）
  * @param  pData: 16字节数据缓冲区
  * @retval 读取状态
  */
char PcdRead(u8 ucAddr, u8 *pData);

/**
  * @brief  使卡片进入休眠状态
  * @retval 固定返回MI_OK
  */
char PcdHalt(void);

/* 应用层接口 ------------------------------------------------------------*/

/**
  * @brief  卡片读写主控函数
  * @param  UID: 卡片UID（输入/输出）
  * @param  KEY: 6字节密钥
  * @param  RW: 操作模式
  *         - 1: 读块数据
  *         - 0: 写块数据
  * @param  Dat: 数据缓冲区
  */
void IC_CMT(u8 *UID, u8 *KEY, u8 RW, u8 *Dat);

/**
  * @brief  显示卡片UID
  * @param  x,y: 显示坐标
  * @param  p: UID指针（4字节）
  * @param  charColor: 字符颜色（RGB565）
  * @param  bkColor: 背景颜色（RGB565）
  */
void ShowID(u16 x, u16 y, u8 *p, u16 charColor, u16 bkColor);

#endif

/***************************** END OF FILE *********************************/